package controller 
{
	import flash.utils.Dictionary;
	import model.MAsteroid;
	import model.MGameboard;
	import model.MSpaceship;
	import statemachine.IConditionsChecker;
	import statemachine.IStateObject;
	/**
	 * ...
	 * @author vkozhaev
	 */
	public class ConditionsChecker implements IConditionsChecker
	{
		
		public static const IS_ENERGY_LOW:String = "IS_ENERGY_LOW";
		public static const IS_ASTEROID_NEAR_SHIP:String = "IS_ASTEROID_NEAR_SHIP";
		public static const IS_ASTEROID_NOT_NEAR_SHIP:String = "IS_ASTEROID_NOT_NEAR_SHIP";
		public static const IS_ENERGY_NULL:String = "IS_ENERGY_NULL";
		public static const IS_CARGO_BAY_FULL:String = "IS_CARGO_BAY_FULL";
		public static const IS_CARGO_BAY_NOT_FULL:String = "IS_CARGO_BAY_NOT_FULL";
		public static const IS_SPACESHIP_NEAR_SERVICE:String = "IS_SPACESHIP_NEAR_SERVICE";
		public static const IS_SPACESHIP_NOT_NEAR_SERVICE:String = "IS_SPACESHIP_NOT_NEAR_SERVICE";
		public static const UNCONDITION_JUMP:String = "UNCONDITION_JUMP";
		
		
		private var _gameboard:MGameboard;
		
		
		private var _conditions:Dictionary;
		
		
		public function ConditionsChecker(_gameboard:MGameboard) 
		{
			this._gameboard = _gameboard;
			_conditions = new Dictionary();
			_conditions[IS_ENERGY_LOW] =isEnergyLow ;
			_conditions[IS_ASTEROID_NEAR_SHIP] = isAsteroidNearShip;
			_conditions[IS_ENERGY_NULL] = isEnergyNull;
			_conditions[IS_CARGO_BAY_FULL] = isCargoBayFull ;
			_conditions[IS_CARGO_BAY_NOT_FULL] = isCargoBayNotFull ;
			_conditions[IS_ASTEROID_NOT_NEAR_SHIP] = isAsteroidNotNearShip;
			_conditions[IS_SPACESHIP_NEAR_SERVICE] = isSpaceshipNearService;
			_conditions[IS_SPACESHIP_NOT_NEAR_SERVICE] = isSpaceshipNotNearService;
			_conditions[UNCONDITION_JUMP] = unconditionJump;
			
			
		}
		
		public function getCondition(conditionName:String):Function {
			return _conditions[conditionName] as Function;
		}
		 
		/**
		 * Безусловный переход
		 * @param	stateObject
		 * @return true всегда
		 */
		public function unconditionJump(stateObject:IStateObject):Boolean {
			trace("call unconditions jump")
			return true;
		}
		
		
		/**
		 * Если энергии мало, нужно лететь на подзарядку
		 * @param	stateObject - корабль
		 * @param	parameters - не используется в данной ф - ции.
		 * @return true если мало энергии, false в другом случае
		 */
		public function isEnergyLow(stateObject:IStateObject):Boolean {
			return (stateObject as MSpaceship).energy<SetParameters.BASE_ENERGY
		}
		
		/**
		 * Проверка нашли мы астероид или нет
		 * Если нашли, кораблю присваивается астероид
		 * @param	stateObject - корабль
		 * @param	parameters - не используется
		 * @return true если есть, false в другом случае
		 */
		public function isAsteroidNearShip(stateObject:IStateObject):Boolean {
			var asteroids:Vector.<MAsteroid> = _gameboard.asteroids;
			var ship:MSpaceship = stateObject as MSpaceship;
			
			for each (var asteroid:MAsteroid in asteroids) {
				if (asteroid.cellCoords.equals(ship.cellCoords)) {
					ship.processedAsteroid = asteroid;
					return true;
				}
			}
			
			return false;
		}
		
		public function isSpaceshipNearService(stateObject:IStateObject):Boolean {
			var ship:MSpaceship = stateObject as MSpaceship;
			return ship.cellCoords.equals(_gameboard.serviceStation.cellCoords);
		}
		
		
		public function isSpaceshipNotNearService(stateObject:IStateObject):Boolean {
			
			return !isSpaceshipNearService(stateObject);
		}
		public function isAsteroidNotNearShip(stateObject:IStateObject):Boolean {
			return !isAsteroidNearShip(stateObject);
		}
		
		public function isEnergyNull(stateObject:IStateObject):Boolean {
			var ship:MSpaceship = stateObject as MSpaceship;
			
			return ship.energy <= 0;
		}
		
		public function isCargoBayFull(stateObject:IStateObject):Boolean {
			var ship:MSpaceship = stateObject as MSpaceship;
			return ship.cargoBay == SetParameters.CARGO_BAY_SIZE;
		}
		
		
		public function isCargoBayNotFull(stateObject:IStateObject):Boolean {
			
			return !(isCargoBayFull(stateObject));
		}
		
	}

}